package com.skyolder.milkbee.web.rest;

import com.codahale.metrics.annotation.Timed;
import com.skyolder.milkbee.domain.Card;
import com.skyolder.milkbee.domain.Comment;
import com.skyolder.milkbee.domain.Leaguer;
import com.skyolder.milkbee.domain.Moderator;
import com.skyolder.milkbee.domain.User;
import com.skyolder.milkbee.dto.SimpleResult;
import com.skyolder.milkbee.service.CardService;
import com.skyolder.milkbee.service.CommentService;
import com.skyolder.milkbee.service.LeaguerService;
import com.skyolder.milkbee.service.ModeratorService;
import com.skyolder.milkbee.service.UserService;
import com.skyolder.milkbee.security.SecurityUtils;
import com.skyolder.milkbee.web.rest.util.HeaderUtil;
import com.skyolder.milkbee.web.rest.util.PaginationUtil;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.inject.Inject;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * REST controller for managing Comment.
 */
@RestController
@RequestMapping("/api")
public class CommentResource {

	private final Logger log = LoggerFactory.getLogger(CommentResource.class);

	@Inject
	private CommentService commentService;
	@Inject
	private CardService cardService;
	@Inject
	private UserService userService;
	@Inject
	private LeaguerService leaguerService;
	@Inject
	private ModeratorService moderatorService;

	/**
	 * POST /comments : Create a new comment.
	 *
	 * @param comment
	 *            the comment to create
	 * @return the ResponseEntity with status 201 (Created) and with body the
	 *         new comment, or with status 400 (Bad Request) if the comment has
	 *         already an ID
	 * @throws URISyntaxException
	 *             if the Location URI syntax is incorrect
	 */
	@PostMapping("/comments")
	@Timed
	public ResponseEntity<Comment> createComment(@RequestBody Comment comment) throws URISyntaxException {
		log.debug("REST request to save Comment : {}", comment);
		if (comment.getId() != null) {
			return ResponseEntity.badRequest().headers(
					HeaderUtil.createFailureAlert("comment", "idexists", "A new comment cannot already have an ID"))
					.body(null);
		}
		Optional<User> ouser = userService.getUserWithAuthoritiesByLogin(SecurityUtils.getCurrentUserLogin());
		Card card = cardService.findOne(comment.getCardId());
		if (card != null) {
			card.setCommentCount(card.getCommentCount() + 1);
			cardService.save(card);
			comment.setSeq(card.getCommentCount());
			comment.setCategoryId(card.getCategoryId());
		}
		comment.setLight(0L);
		comment.setAccusation(0L);
		comment.setAuthor(SecurityUtils.getCurrentUserLogin());
		comment.setCreatedAt(ZonedDateTime.now());
		ouser.ifPresent((user) -> {
			comment.setUserId(user.getId());
			// card.setLeaguerId();
			Leaguer l = leaguerService.findByUser(user);
			l.setCommentCount(l.getCommentCount() + 1L);
			leaguerService.save(l);
			comment.setLeaguerId(l.getId());
		});
		Comment result = commentService.save(comment);
		return ResponseEntity.created(new URI("/api/comments/" + result.getId()))
				.headers(HeaderUtil.createEntityCreationAlert("comment", result.getId().toString())).body(result);
	}

	/**
	 * PUT /comments : Updates an existing comment.
	 *
	 * @param comment
	 *            the comment to update
	 * @return the ResponseEntity with status 200 (OK) and with body the updated
	 *         comment, or with status 400 (Bad Request) if the comment is not
	 *         valid, or with status 500 (Internal Server Error) if the comment
	 *         couldnt be updated
	 * @throws URISyntaxException
	 *             if the Location URI syntax is incorrect
	 */
	@PutMapping("/comments")
	@Timed
	public ResponseEntity<Comment> updateComment(@RequestBody Comment comment) throws URISyntaxException {
		log.debug("REST request to update Comment : {}", comment);
		if (comment.getId() == null) {
			return createComment(comment);
		}
		Comment result = commentService.save(comment);
		return ResponseEntity.ok().headers(HeaderUtil.createEntityUpdateAlert("comment", comment.getId().toString()))
				.body(result);
	}

	/**
	 * GET /comments : get all the comments.
	 *
	 * @param pageable
	 *            the pagination information
	 * @return the ResponseEntity with status 200 (OK) and the list of comments
	 *         in body
	 * @throws URISyntaxException
	 *             if there is an error to generate the pagination HTTP headers
	 */
	@GetMapping("/comments")
	@Timed
	public ResponseEntity<List<Comment>> getAllComments(@ApiParam Pageable pageable) throws URISyntaxException {
		log.debug("REST request to get a page of Comments");
		Page<Comment> page = commentService.findAll(pageable);
		HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/comments");
		return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
	}

	/**
	 * GET /comments/:id : get the "id" comment.
	 *
	 * @param id
	 *            the id of the comment to retrieve
	 * @return the ResponseEntity with status 200 (OK) and with body the
	 *         comment, or with status 404 (Not Found)
	 */
	@GetMapping("/comments/{id}")
	@Timed
	public ResponseEntity<Comment> getComment(@PathVariable Long id) {
		log.debug("REST request to get Comment : {}", id);
		Comment comment = commentService.findOne(id);
		return Optional.ofNullable(comment).map(result -> new ResponseEntity<>(result, HttpStatus.OK))
				.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
	}

	/**
	 * DELETE /comments/:id : delete the "id" comment.
	 *
	 * @param id
	 *            the id of the comment to delete
	 * @return the ResponseEntity with status 200 (OK)
	 */
	@DeleteMapping("/comments/{id}")
	@Timed
	public ResponseEntity<Void> deleteComment(@PathVariable Long id) {
		log.debug("REST request to delete Comment : {}", id);
		commentService.delete(id);
		return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert("comment", id.toString())).build();
	}

	@GetMapping("/comment/light/{id}")
	@Timed
	public ResponseEntity<SimpleResult> light(@PathVariable Long id) throws URISyntaxException {
		SimpleResult sr = new SimpleResult();
		Comment one = commentService.findOne(id);
		if (one != null) {
			// one.get
			one.setLight((one.getLight()==null?0:one.getLight()) + 1);
			commentService.save(one);
			sr.setSuccess(true);
		}
		return new ResponseEntity<>(sr, HttpStatus.OK);
	}
	
	@GetMapping("/comment/accusation/{id}")
	@Timed
	public ResponseEntity<SimpleResult> accusation(@PathVariable Long id) throws URISyntaxException {
		SimpleResult sr = new SimpleResult();
		Comment one = commentService.findOne(id);
		if (one != null) {
			one.setAccusation((one.getAccusation()==null?0:one.getAccusation()) + 1);
			commentService.save(one);
			sr.setSuccess(true);
		}
		return new ResponseEntity<>(sr, HttpStatus.OK);
	}
	
	@GetMapping("/modcomment")
	@Timed
	public ResponseEntity<List<Comment>> getAllModComments(@ApiParam Pageable pageable) throws URISyntaxException {
		log.debug("REST request to get a page of Categories");
		Optional<User> ouser = userService.getUserWithAuthoritiesByLogin(SecurityUtils.getCurrentUserLogin());
		User user = ouser.get();
		Long userId = user.getId();
		List<Moderator> moderators=moderatorService.findByUserId(userId);
		List<Long> categoryIds=new ArrayList<Long>();
		for(Moderator m:moderators){
			categoryIds.add(m.getCategoryId());
		}
		
		Page<Comment> page = commentService.doqueryInCategories(categoryIds,pageable);
		HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/comments");
		return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
	}
	
	@PutMapping("/moder/forbiddenbycomment/{id}")
	@Timed
	public ResponseEntity<SimpleResult> updateComment(@PathVariable Long id) throws URISyntaxException {
		Comment comment=commentService.findOne(id);
		Long leaguerId=comment.getLeaguerId();
		
		//Comment result = commentService.save(comment);
		SimpleResult sr = new SimpleResult();
		return new ResponseEntity<>(sr, HttpStatus.OK);
	}
}
